<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <title>事件循环</title>
  <style></style>
</head>

<body>
  <script>
    /**
     * 参考博客：http://www.ruanyifeng.com/blog/2014/10/event-loop.html
     * 参考博客：https://www.cnblogs.com/chenwenhao/p/11253403.html
     * 参考博客：https://juejin.cn/post/6844903512845860872
     *
     * 1.事件循环（Event Loop）：主线程从"任务队列"中读取事件，这个过程是循环不断的，这种运行机制又称为事件循环。
     *   宏任务：script(整体代码)、setTimeout、setInterval、setImmediate、VO、UI rendering
     *   微任务：promise、Object observe、MutationObserver
     *   任务的优先级：process.nextTick>promise.then>setTimeout>setImmediate
     *   微任务一直跟着当前宏任务后面，代码执行到一个微任务就跟上，一个接着一个
     *
     * js做异步操作的时候，利用的是事件循环操作
     *
     * 2. 为什么JavaScript不能有多个线程?
     *   JavaScript的单线程，与它的用途有关。作为浏览器脚本语言，JavaScript的主要用途是与用户互动，以及操作DOM。
     *   这决定了它只能是单线程，否则会带来很复杂的同步问题。
     *   例如：假定JavaScript同时有两个线程，一个线程在某个DOM节点上添加内容，
     *      另一个线程删除了这个节点，这时浏览器应该以哪个线程为准？
     *
     * 3.同步(sync)与异步(async)：
     *   同步:在主线程上排队执行的任务，只有前一个任务执行完毕，才能执行后一个任务;
     *   异步：不进入主线程，而进入"任务队列"的任务，只有"任务队列"通知主线程，某个异步任务可以执行了，该任务才会进入主线程执行;
     *
     * 4.js执行机制(异步/同步执行)步骤：
     *   (1)js是单线程，执行顺序是从上而下执行，所有的同步任务都会在主线程（执行栈）中执行；
     *   (2)当执行到某个异步函数时，会将此异步任务放入到"异步队列"中，等待执行；
     *   (3)当主线程（执行栈）的同步任务全部执行完后,会检查主线程执行栈是否清空，
     *      若主线程执行栈清空，则去检查“异步队列”中是否还有未执行的任务；若有，则放入到主线程中执行；
     *      若主线程执行栈被清空，然后再去“异步队列”中读取任务，再执行，循环往复；
     *   (4)单个过程叫做“js执行机制”，重复的过程叫做“事件循环”;
     *   说明：宏任务进入队列，微任务会挂载宏任务后面，执行时，优先执行微任务，然后再执行宏任务；
     * */

    console.log(1);

    setTimeout(function () {
      console.log(2);
    }, 10);

    new Promise(function (resolve) {
      console.log(3);
      for (var i = 100000; i > 0; i--) {
        i == 1 && resolve();
      }
      console.log(4);
    })
      .then(function () {
        console.log(5);
      })
      .then(function () {
        console.log(6);
      });

    console.log(7);
  </script>
</body>

</html>